<template>
    <div class="ph-input-wrap ph-select-wrap ph-icon-arrow ph-icon-arrow-down" ref="edropdown">
        <ph-input @click="toggle" :value="text" :disabled="disabled" :placeholder="placeholder" :readonly="true" class="ph-select"/>
        <teleport :to="'#'+id">
            <dropdown-list 
                :align="align"
                :visible="visible"
                :style="dropdownStyle"
                :theme="theme"
                :disabled="disabled"
                :actionsheet="state.actionsheet"
                :title="actionsheetTitle"
                :multiple="multiple"
                :animation="animation"
                @hide="visible=false"
                @done="onDone"
                >
                <slot></slot>
            </dropdown-list>
        </teleport>
    </div>
</template>
<script lang="ts">
import { computed, defineComponent, provide, ref, toRef, unref, nextTick, reactive } from 'vue'
import { createLayer } from '../../../shared/use'
import getPosition from 'ph-position'
import PhInput from '../input.vue'
import DropdownList from './option-list.vue'
import MediaQuery from 'ph-media'

interface Opt{
    value:string|number,
    text:string,
    selected?:boolean
}
export default defineComponent({
    components:{PhInput,DropdownList},
    props:{
        disabled:{type:Boolean,default:false},
        multiple:{type:Boolean,default:false},
        placeholder:{type:String},
        value:{type:[String,Number,Array]},
        align:{type:String,default:'left'},
        theme:{type:String,default:'light'},
        animation:String,
        actionsheetTitle:String
    },
    setup(props,{emit,slots}){
        const { id, layer } = createLayer()
        const state = reactive({
            actionsheet:false
        })

        const dropdownStyle = reactive({
            left:"0px",
            top:"0px"
        })
        const edropdown = ref<HTMLElement>()
        const visible = ref(false)
        const options = ref<Opt[]>([])
        const cacheValues = ref<Array<string|number>>([])
        const values = computed<Array<string|number>>(()=>{
            if(!props.value)return []
            if(props.multiple){
                if(props.value instanceof Array)return props.value as Array<string|number>
                else return [props.value] as Array<string|number>
            }
            return [props.value] as Array<string|number>
        })
        const text = computed(()=>{
            const res = options.value.filter((d:Opt)=>values.value.includes(d.value))
            const text = res.map((opt:Opt)=>opt.text).join(",")
            return text?text:''
        })
        const inputcn = computed(()=>{
            return {
                'ph-select-handle':true,
                'ph-placeholder':!text.value
            }
        })
        const initCacheValues = ()=>{
            values.value.forEach((a)=>cacheValues.value.push(a))
        }
        const addOption = (data:Opt)=>{
            const duplicated =options.value.some(opt=>opt.value===data.value)
            if(duplicated)return
            options.value.push(data)
        }
        const update = (opt:Opt)=>{
            if(props.multiple){
                if(opt.selected)cacheValues.value.push(opt.value)
                else cacheValues.value.splice(cacheValues.value.indexOf(opt.value),1)
            }else{
                visible.value = false
                cacheValues.value = [opt.value]
                emit('change',opt.value)
            }
        }
        const onDone = ()=>{
            visible.value = false
            //断开引用
            emit('change',[...unref(cacheValues)] )
        }
        const toggle = ()=>{
            if(props.disabled)return
            visible.value=!visible.value
            if(visible.value)
            nextTick(()=>{
                const 
                    list = (layer.querySelector(".ph-drowdown-list")) as HTMLElement,
                    prect = edropdown.value?.getBoundingClientRect() as DOMRect;
                list.style.minWidth = prect.width+"px";
                setTimeout(()=>{
                    const {offsetHeight,offsetWidth} = list,
                        {x,y} = getPosition({offsetHeight,offsetWidth},prect,{top:true});
                    dropdownStyle.left = x+"px"
                    dropdownStyle.top = y+"px"
                })
            })
        }
        provide("update",update)
        provide("addOption",addOption)
        provide("cvalue",cacheValues)
        provide("multiple",toRef(props,'multiple'))
        initCacheValues()

        MediaQuery.maxWidth("375px",(matches)=>{
            state.actionsheet =	matches
        })
        return {visible,text,onDone,inputcn,toggle,edropdown,dropdownStyle,id,state}
    }
})
</script>

<style lang="scss">
.ph-select-wrap{
    overflow: visible;
    position: relative;
    .ph-select{
        cursor: pointer;
        position: relative;
        z-index: 1;
        width: 100%;
        background-color: transparent;
    }
}
</style>